home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP06.ZIP / CHAP06 / DATAUSER / IADVSINK.CPP < prev    next >
C/C++ Source or Header  |  1993-04-14  |  7KB  |  304 lines

  1. /*
  2.  * IADVSINK.CPP
  3.  *
  4.  * Implementation of the IAdviseSink interface for the Data User, Chapter 6
  5.  *
  6.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  7.  *
  8.  * Kraig Brockschmidt, Software Design Engineer
  9.  * Microsoft Systems Developer Relations
  10.  *
  11.  * Internet  :  kraigb@microsoft.com
  12.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  13.  */
  14.  
  15.  
  16. #include "datauser.h"
  17.  
  18.  
  19. /*
  20.  * CImpIAdviseSink::CImpIAdviseSink
  21.  * CImpIAdviseSink::~CImpIAdviseSink
  22.  *
  23.  * Parameters (Constructor):
  24.  *  pAV             LPAPPVARS to the application
  25.  *
  26.  */
  27.  
  28. CImpIAdviseSink::CImpIAdviseSink(LPAPPVARS pAV)
  29.     {
  30.     m_cRef=0;
  31.     m_pAV=pAV;
  32.     return;
  33.     }
  34.  
  35. CImpIAdviseSink::~CImpIAdviseSink(void)
  36.     {
  37.     return;
  38.     }
  39.  
  40.  
  41.  
  42.  
  43. /*
  44.  * CImpIAdviseSink::QueryInterface
  45.  * CImpIAdviseSink::AddRef
  46.  * CImpIAdviseSink::Release
  47.  *
  48.  * Purpose:
  49.  *  IUnknown members for CImpIAdviseSink object.
  50.  */
  51.  
  52. STDMETHODIMP CImpIAdviseSink::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  53.     {
  54.     *ppv=NULL;
  55.  
  56.     //Any interface on this object is the object pointer.
  57.     if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IAdviseSink))
  58.         *ppv=(LPVOID)this;
  59.  
  60.     /*
  61.      * If we actually assign an interface to ppv we need to AddRef it
  62.      * since we're returning a new pointer.
  63.      */
  64.     if (NULL!=*ppv)
  65.         {
  66.         ((LPUNKNOWN)*ppv)->AddRef();
  67.         return NOERROR;
  68.         }
  69.  
  70.     return ResultFromScode(E_NOINTERFACE);
  71.     }
  72.  
  73.  
  74. STDMETHODIMP_(ULONG) CImpIAdviseSink::AddRef(void)
  75.     {
  76.     return ++m_cRef;
  77.     }
  78.  
  79.  
  80. STDMETHODIMP_(ULONG) CImpIAdviseSink::Release(void)
  81.     {
  82.     ULONG   cRefT;
  83.  
  84.     cRefT=--m_cRef;
  85.  
  86.     if (0==cRefT)
  87.         delete this;
  88.  
  89.     return cRefT;
  90.     }
  91.  
  92.  
  93.  
  94.  
  95. /*
  96.  * IAdviseSink::OnDataChange
  97.  *
  98.  * Purpose:
  99.  *  Notifes the advise sink that data changed in a data object.  On
  100.  *  this message you may request a new data rendering and update your
  101.  *  displays as necessary.  Any data sent to this function is owned
  102.  *  by the caller, not by this advise sink!
  103.  *
  104.  *  All Advise Sink methods should be considered asynchronous and therefore
  105.  *  we should attempt no synchronous calls from within them to an EXE
  106.  *  object.  If we do, we'll get RPC_E_CALLREJECTED as shown below.
  107.  *
  108.  * Parameters:
  109.  *  pFE             LPFORMATETC describing format that changed
  110.  *  pSTM            LPSTGMEDIUM providing the medium in which the data
  111.  *                  is provided.
  112.  *
  113.  * Return Value:
  114.  *  None
  115.  */
  116.  
  117. STDMETHODIMP_(void) CImpIAdviseSink::OnDataChange(LPFORMATETC pFE
  118.     , LPSTGMEDIUM pSTM)
  119.     {
  120.     BOOL        fUsable=TRUE;
  121.     UINT        cf;
  122.     STGMEDIUM   stm;
  123.  
  124.     /*
  125.      * We first check that the changed data is, in fact, a format we're
  126.      * interested in, either CF_TEXT, CF_BITMAP, or CF_METAFILEPICT, then
  127.      * only in the aspects we want.  We then check if pSTM->tymed is
  128.      * TYMED_NULL or something else.  If NULL, we just exit so the
  129.      * data object can time ADVF_NODATA transactions.  Otherwise we
  130.      * verify that the data is useful and repaint.
  131.      *
  132.      * If there is data in pSTM we are responsible for it.
  133.      */
  134.  
  135.     //Ignore the m_fGetData flag for EXE objects (we can't GetData)
  136.     if (!m_pAV->m_fGetData && !m_pAV->m_fEXE)
  137.         return;
  138.  
  139.     //See if we're interested
  140.     cf=pFE->cfFormat;
  141.  
  142.     if ((CF_TEXT!=cf && CF_BITMAP!=cf && CF_METAFILEPICT!=cf)
  143.         || !(DVASPECT_CONTENT & pFE->dwAspect))
  144.         return;
  145.  
  146.     //Check media types
  147.     switch (cf)
  148.         {
  149.         case CF_TEXT:
  150.             fUsable=(BOOL)(TYMED_HGLOBAL & pFE->tymed);
  151.             break;
  152.  
  153.         case CF_BITMAP:
  154.             fUsable=(BOOL)(TYMED_GDI & pFE->tymed);
  155.             break;
  156.  
  157.         case CF_METAFILEPICT:
  158.             fUsable=(BOOL)(TYMED_MFPICT & pFE->tymed);
  159.             break;
  160.  
  161.         default:
  162.             break;
  163.         }
  164.  
  165.     if (!fUsable)
  166.         return;
  167.  
  168.     if (NULL==m_pAV->m_pIDataObject)
  169.         return;
  170.  
  171.     /*
  172.      * When dealing with EXE objects, invalidate ourselves
  173.      * after setting TYMED_NULL in our STGMEDIUM that causes
  174.      * CAppVars::Paint to request new data.  We cannot call
  175.      * ::GetData in here because this is an async call when we're
  176.      * dealing with an EXE.
  177.      */
  178.     if (m_pAV->m_fEXE)
  179.         {
  180.         ReleaseStgMedium(&(m_pAV->m_stm));
  181.         m_pAV->m_cf=cf;
  182.         m_pAV->m_stm.tymed=TYMED_NULL;
  183.  
  184.         InvalidateRect(m_pAV->m_hWnd, NULL, TRUE);
  185.         return;
  186.         }
  187.  
  188.     if (FAILED(m_pAV->m_pIDataObject->GetData(pFE, &stm)))
  189.         return;
  190.  
  191.     //Get rid of old data and update.
  192.     ReleaseStgMedium(&(m_pAV->m_stm));
  193.  
  194.     m_pAV->m_cf=cf;
  195.     m_pAV->m_stm=stm;
  196.  
  197.     InvalidateRect(m_pAV->m_hWnd, NULL, TRUE);
  198.  
  199.     if (m_pAV->m_fRepaint)
  200.         UpdateWindow(m_pAV->m_hWnd);
  201.  
  202.     return;
  203.     }
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211. /*
  212.  * IAdviseSink::OnViewChange
  213.  *
  214.  * Purpose:
  215.  *  Notifes the advise sink that presentation data changed in the data
  216.  *  object to which we're connected providing the right time to update
  217.  *  displays using such presentations.
  218.  *
  219.  * Parameters:
  220.  *  dwAspect        DWORD indicating which aspect has changed.
  221.  *  lindex          LONG indicating the piece that changed.
  222.  *
  223.  * Return Value:
  224.  *  None
  225.  */
  226.  
  227. STDMETHODIMP_(void) CImpIAdviseSink::OnViewChange(DWORD dwAspect, LONG lindex)
  228.     {
  229.     return;
  230.     }
  231.  
  232.  
  233.  
  234.  
  235.  
  236. /*
  237.  * IAdviseSink::OnRename
  238.  *
  239.  * Purpose:
  240.  *  Informs the advise sink that an IOleObject has been renamed, primarily
  241.  *  when its linked.
  242.  *
  243.  * Parameters:
  244.  *  pmk             LPMONIKER providing the new name of the object
  245.  *
  246.  * Return Value:
  247.  *  None
  248.  */
  249.  
  250. STDMETHODIMP_(void) CImpIAdviseSink::OnRename(LPMONIKER pmk)
  251.     {
  252.     return;
  253.     }
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260. /*
  261.  * IAdviseSink::OnSave
  262.  *
  263.  * Purpose:
  264.  *  Informs the advise sink that the OLE object has been saved
  265.  *  persistently.  The primary purpose of this is for containers that
  266.  *  want to make optimizations for objects that are not in a saved
  267.  *  state, so on this you have to disable such optimizations.
  268.  *
  269.  * Parameters:
  270.  *  None
  271.  *
  272.  * Return Value:
  273.  *  None
  274.  */
  275.  
  276. STDMETHODIMP_(void) CImpIAdviseSink::OnSave(void)
  277.     {
  278.     return;
  279.     }
  280.  
  281.  
  282.  
  283.  
  284.  
  285. /*
  286.  * IAdviseSink::OnClose
  287.  *
  288.  * Purpose:
  289.  *  Informs the advise sink that the OLE object has closed and is
  290.  *  no longer bound in any way.  On this you typically change state
  291.  *  variables and redraw shading, etc.
  292.  *
  293.  * Parameters:
  294.  *  None
  295.  *
  296.  * Return Value:
  297.  *  None
  298.  */
  299.  
  300. STDMETHODIMP_(void) CImpIAdviseSink::OnClose(void)
  301.     {
  302.     return;
  303.     }
  304.